package com.samp.base.nio;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;

/**
 * 参考：https://www.cnblogs.com/digdeep/p/4478734.html
 * @author EX-WANWEI001
 *
 */
public class NioDemo {

	private static String path = "D:\\nas\\samp\\temp\\";
	private static  String fileName = "nio_demo.txt";
	
	/**
	 * 常用操作：创建文件夹，创建文件，写文件。
	 * @throws IOException
	 */
	@SuppressWarnings("unused")
	private static void writeDemo() throws IOException{
		/*
		 * StandardOpenOption.CREATE:没有就创建，有就清空内容。
		 * StandardOpenOption.TRUNCATE_EXISTING:没有会报错，有就清空内容。
		 * StandardOpenOption.APPEND:在后面添加内容，如果文件不存在，也会先创建文件。
		 */
		Path dirPath = Paths.get(path);
		if( !Files.exists(dirPath) ){
			Files.createDirectory(dirPath);
		}
		Path filePath = Paths.get(path+fileName);
		if( !Files.exists(filePath) ){
			Files.createFile(filePath);
		}
		String[] datas = {"张三","李四","王麻子",};
		List<String> dataList = Arrays.asList(datas);
		Files.write(filePath, dataList, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
		//注意，直接添加字符串，不会在后面加回车，需要自己手工添加
		Files.write(filePath, "字符串添加1".getBytes(),   StandardOpenOption.APPEND);
		/*		加上换行符 \r是回车符,\n是新行。
			\r Mac 
			\n Unix/Linux 
			\r\n Windows
		 */
		// System.lineSeparator()  同  System.getProperty("line.separator")
		Files.write(filePath, System.lineSeparator() .getBytes(),   StandardOpenOption.APPEND); 
		Files.write(filePath, "字符串添加2".getBytes(),   StandardOpenOption.APPEND);
		Files.write(filePath, "\r\n".getBytes(),   StandardOpenOption.APPEND); 
		Files.write(filePath, "字符串添加3".getBytes(),   StandardOpenOption.APPEND);
	}
	
	/**
	 * 用BufferReader读取文件。
	 * @throws Exception
	 */
	@SuppressWarnings("unused")
	private static void readDemo() throws Exception{
		Path filePath = Paths.get(path+fileName);
		BufferedReader bufferReader = Files.newBufferedReader(filePath, StandardCharsets.UTF_8);
		String line = null;
		try {
			while( (line = bufferReader.readLine()) != null ){
				System.out.println(line);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			bufferReader.close();
		}
	}
	
	/**
	 * 用BufferWriter写文件
	 * @throws Exception
	 */
	@SuppressWarnings("unused")
	private static void bufferWriterDemo()throws Exception{
		/*
		 * 文件不存在时，会创建新文件，如果存在，则替换内容
		 */
		 BufferedWriter writer = null;
		 try {
	            writer = Files.newBufferedWriter(Paths.get(path+"buffer_writer_demo.txt"), StandardCharsets.UTF_8);
	            writer.write("第一行1");
	            writer.newLine();
	            writer.write("第二行1");
	            writer.flush();
	        } catch (IOException e1) {
	            e1.printStackTrace();
	        }finally{
	        	if( writer != null ){
	        		writer.close();
	        	}
	        }
	}
	
	/**
	 * 遍历单个目录，但不递归。
	 * @throws Exception
	 */
	@SuppressWarnings("unused")
	private static void traversalDirDemo() throws Exception{
		Path dir = Paths.get(path);
		//通过Files.newDirectoryStream(dir)来遍历文件夹
		try( DirectoryStream<Path> stream = Files.newDirectoryStream(dir) ){
            for(Path path : stream){
            	if( Files.isDirectory(path) ){
            		System.out.println(path.getFileName()+"是一个文件夹");
            	}else{
            		System.out.println(path.getFileName()+"是一个文件");
            	}
            }
        }catch(IOException e){
            e.printStackTrace();
        }
		//通过Files.list(dir)也可以遍历一个文件夹。
		try ( Stream<Path> stream = Files.list(dir) ){
            Iterator<Path> ite = stream.iterator();
            while(ite.hasNext()){
                Path path = ite.next();
                if( Files.isDirectory(path) ){
            		System.out.println(path.getFileName()+"是一个文件夹");
            	}else{
            		System.out.println(path.getFileName()+"是一个文件");
            	}
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
	}
	
	/**
	 * 递归遍历一个文件夹。
	 * @throws Exception
	 */
	private static void walkFileTreeDemo() throws Exception{
		Path dir = Paths.get(path);
		List<Path> result = new ArrayList<Path>();
		Files.walkFileTree(dir, new FindJavaVisitor(result));
		System.out.println("result.size()=" + result.size());  
	}
	
	private static class FindJavaVisitor extends SimpleFileVisitor<Path>{
		private List<Path> result;
        public FindJavaVisitor(List<Path> result){
            this.result = result;
        }
		@Override
		public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
			if( Files.isDirectory(file) ){
				//此处永远不会运行到，因为碰到文件夹会进入直接找文件
        		System.out.println(file.getFileName()+"是一个文件夹."+file.toString());
        	}else{
        		System.out.println(file.getFileName()+"是一个文件."+file.toString());
        		if(file.toString().endsWith(".txt")){
                    result.add(file.getFileName());
                }
        	}
			return super.visitFile(file, attrs);
		}
        
	}
	
	public static void main(String[] args) {
		try {
			//writeDemo();
			//readDemo();
			//bufferWriterDemo();
			//traversalDirDemo();
			walkFileTreeDemo();
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("done!");
	}

}
